<?php

App::uses('Tag', 'Model');
App::uses('ConfigurationKeys', 'ConfigurationKeys.Lib');
App::uses('Basics', 'Base.Lib');

class PsfmAdmin {

    public static function customDataModelsClearCache() {
        foreach (self::_customModels() as $model) {
            $model->clearCache();
        }
    }

    public static function customDataModelsAssertInitializedData() {
        foreach (self::_customModels() as $model) {
            $model->assertInitializedData();
        }
    }

    public static function fixFilesPermissions() {
        self::_fixFilesystemObject(ConfigurationKeys::getKeyValue('raw_files_directory'));
        self::_fixFilesystemObject(ConfigurationKeys::getKeyValue('shared_files_directory'));
    }

    public static function updateAllDocumentsTag() {
        self::_updateTag(
                ConfigurationKeys::getKeyValue('all_documents_tag_name'), ClassRegistry::init('SourceDocument')->find('all')
        );
    }

    public static function updateAllDocumentsNonTaggedTag() {
        $SourceDocument = ClassRegistry::init('SourceDocument');
        $sourceDocuments = $SourceDocument->find('all', array(
            'conditions' => array(
                'not ' . $SourceDocument->getVirtualField('tagged')
            )
                ));
        self::_updateTag(
                ConfigurationKeys::getKeyValue('all_documents_non_tagged_tag_name'), $sourceDocuments
        );
    }

    private static function _customModels() {
        $models = array();
        foreach (App::objects('model') as $modelName) {
            $model = ClassRegistry::init($modelName);
            if ($model instanceof CustomDataModel) {
                $models[] = $model;
            }
        }
        return $models;
    }

    private static function _fixFilesystemObject($realPath) {
        if (is_dir($realPath)) {
            chmod($realPath, 0777);
            $it = new DirectoryIterator($realPath);
            while ($it->valid()) {
                if (!$it->isDot()) {
                    self::_fixFilesystemObject($it->getRealPath());
                }
                $it->next();
            }
        } else {
            chmod($realPath, 0666);
        }
    }

    private static function _updateTag($tagName, $sourceDocuments) {
        $tag = ClassRegistry::init('Tag')->findByName($tagName);
        if (empty($tag)) {            
            $tag = Basics::saveModelOrThrowException('Tag', array(
                'Tag' => array(
                    'name' => $tagName
                )
            ));
        }
        $SourceDocumentTag = ClassRegistry::init('SourceDocumentTag');
        $ids = array();

        foreach ($sourceDocuments as $sourceDocument) {
            $ids[$sourceDocument['SourceDocument']['id']] = true;
            $sourceDocumentTag = $SourceDocumentTag->findBySourceDocumentAndTag(
                    $sourceDocument['SourceDocument']['id'], $tag['Tag']['id']
            );
            if (empty($sourceDocumentTag)) {
                $sourceDocumentTag['SourceDocumentTag'] = array(
                    'tag_id' => $tag['Tag']['id'],
                    'source_document_id' => $sourceDocument['SourceDocument']['id'],
                );
                $SourceDocumentTag->create();
                Basics::saveModelOrThrowException($SourceDocumentTag, $sourceDocumentTag);
            }
            else {
                $SourceDocumentTag->complete($sourceDocumentTag);
            }
        }
                        
        //Remove documentos excented
        self::_removeTagOverSourceDocuments($tag['Tag']['id'], array_keys($ids));
    }
    
    public static function _removeTagOverSourceDocuments($tagId, $sourceDocumentIds) {        
        foreach(ClassRegistry::init('SourceDocumentTag')->findAllByTagId($tagId) as $sourceDocumentTag) {            
            if (!in_array($sourceDocumentTag['SourceDocumentTag']['source_document_id'], $sourceDocumentIds)) {
                Basics::deleteModelOrThrowException('SourceDocumentTag', $sourceDocumentTag);
            }
        }
    }

}